package cn.csc.module.product.service.spudetail;

import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.mybatis.core.util.MyBatisUtils;
import cn.csc.module.product.controller.admin.spu.vo.SpuDataRespVO;
import cn.csc.module.product.controller.admin.spudetail.vo.SpuDetailCreateReqVO;
import cn.csc.module.product.controller.admin.spudetail.vo.SpuDetailExportReqVO;
import cn.csc.module.product.controller.admin.spudetail.vo.SpuDetailPageReqVO;
import cn.csc.module.product.controller.admin.spudetail.vo.SpuDetailUpdateReqVO;
import cn.csc.module.product.controller.app.spu.vo.AppSpuSearchPageReqVO;
import cn.csc.module.product.convert.spu.SpuConvert;
import cn.csc.module.product.convert.spudetail.SpuDetailConvert;
import cn.csc.module.product.dal.dataobject.spu.SpuDO;
import cn.csc.module.product.dal.dataobject.spudetail.SpuDetailDO;
import cn.csc.module.product.dal.mysql.spu.SpuMapper;
import cn.csc.module.product.dal.mysql.spudetail.SpuDetailMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

import static cn.csc.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.csc.module.product.enums.ErrorCodeConstants.SPU_DETAIL_NOT_EXISTS;

/**
 * 商品详情信息 Service 实现类
 *
 * @author liuchuang
 */
@Service
@Validated
public class SpuDetailServiceImpl implements SpuDetailService {

    @Resource
    private SpuMapper spuMapper;

    @Resource
    private SpuDetailMapper spuDetailMapper;

    @Override
    public BigInteger createSpuDetail(SpuDetailCreateReqVO createReqVO) {
        // 插入
        SpuDetailDO spuDetail = SpuDetailConvert.INSTANCE.convert(createReqVO);
        spuDetailMapper.insert(spuDetail);
        // 返回
        return spuDetail.getId();
    }

    @Override
    public void updateSpuDetail(SpuDetailUpdateReqVO updateReqVO) {
        // 校验存在
        validateSpuDetailExists(updateReqVO.getId());
        // 更新
        SpuDetailDO updateObj = SpuDetailConvert.INSTANCE.convert(updateReqVO);
        spuDetailMapper.updateById(updateObj);
    }

    @Override
    public void deleteSpuDetail(BigInteger id) {
        // 校验存在
        validateSpuDetailExists(id);
        // 删除
        spuDetailMapper.deleteById(id);
    }

    private void validateSpuDetailExists(BigInteger id) {
        if (spuDetailMapper.selectById(id) == null) {
            throw exception(SPU_DETAIL_NOT_EXISTS);
        }
    }

    @Override
    public SpuDetailDO getSpuDetail(BigInteger id) {
        return spuDetailMapper.selectById(id);
    }

    @Override
    public List<SpuDetailDO> getSpuDetailList(Collection<BigInteger> ids) {
        return spuDetailMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<SpuDetailDO> getSpuDetailPage(SpuDetailPageReqVO pageReqVO) {
        return spuDetailMapper.selectPage(pageReqVO);
    }

    @Override
    public List<SpuDetailDO> getSpuDetailList(SpuDetailExportReqVO exportReqVO) {
        return spuDetailMapper.selectList(exportReqVO);
    }

    @Override
    public List<SpuDetailDO> selectListDetailNum() {
        return spuDetailMapper.selectListDetailNum();
    }

    @Override
    public void detailNum(BigInteger id) {
           spuDetailMapper.updateSpuLookNum(id);
    }

    @Override
    public List<SpuDataRespVO> getHot(){
        List<SpuDetailDO> hot = spuDetailMapper.getHot();
        if (hot.size() < 10){
            return new ArrayList<>();
        } else {
            // 打乱集合中元素顺序
            Collections.shuffle(hot);
            List<SpuDetailDO> collect = hot.stream().limit(5).collect(Collectors.toList());
            List<SpuDO> spuDOS = spuMapper.selectBatchIds(collect.stream().map(SpuDetailDO::getId).collect(Collectors.toList()));
            Map<BigInteger, SpuDetailDO> spuDetailDOMap = collect.stream().collect(Collectors.toMap(SpuDetailDO::getId, obj -> obj, (m1, m2) -> m2));
            return SpuConvert.INSTANCE.convertList2(spuDOS).stream().peek(
                    spu -> {
                        spu.setDetail(spuDetailDOMap.get(spu.getId()).getDetail());
                        spu.setDetailImg(spuDetailDOMap.get(spu.getId()).getDetailImg());
                    }
            ).collect(Collectors.toList());
        }
    }

    @Override
    public PageResult<SpuDataRespVO> searchLikeSpuName(AppSpuSearchPageReqVO pageReqVO){
        IPage<SpuDataRespVO> mpPage = MyBatisUtils.buildPage(pageReqVO);
        spuMapper.searchLikeSpuNamePage(pageReqVO, mpPage);
        long totalPage;
        if (mpPage.getTotal() > 0) {
            if (mpPage.getTotal() % pageReqVO.getPageSize() <= 0)
                totalPage = mpPage.getTotal() / pageReqVO.getPageSize();
            else
                totalPage = (mpPage.getTotal() / pageReqVO.getPageSize()) + 1;
        } else {
            return new PageResult<>();
        }

        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal(), totalPage);
    }


}
